/* global CodeMirror define */
/**
 * THIS IS A FORK OF ADDON/FOLD/MARKDOWN-FOLD
 *
 * See: https://codemirror.net/addon/fold/markdown-fold.js
 *
 * This is necessary, because our mode basically _is_
 * Markdown, but it can't be named as such.
 */

(function (mod) {
  if (typeof exports === 'object' && typeof module === 'object') { // CommonJS
    mod(require('codemirror/lib/codemirror'))
  } else if (typeof define === 'function' && define.amd) { // AMD
    define(['codemirror/lib/codemirror'], mod)
  } else { // Plain browser env
    mod(CodeMirror)
  }
})(function (CodeMirror) {
  'use strict'

  CodeMirror.registerHelper('fold', 'markdown', function (cm, start) {
    var maxDepth = 100

    function isHeader (lineNo) {
      var tokentype = cm.getTokenTypeAt(CodeMirror.Pos(lineNo, 0))
      return tokentype && /\bheader\b/.test(tokentype)
    }

    function headerLevel (lineNo, line, nextLine) {
      var match = line && line.match(/^#+/)
      if (match && isHeader(lineNo)) return match[0].length
      match = nextLine && nextLine.match(/^[=-]+\s*$/)
      if (match && isHeader(lineNo + 1)) return nextLine[0] === '=' ? 1 : 2
      return maxDepth
    }

    var firstLine = cm.getLine(start.line)
    var nextLine = cm.getLine(start.line + 1)
    var level = headerLevel(start.line, firstLine, nextLine)
    if (level === maxDepth) return undefined

    var lastLineNo = cm.lastLine()
    var end = start.line
    var nextNextLine = cm.getLine(end + 2)
    while (end < lastLineNo) {
      if (headerLevel(end + 1, nextLine, nextNextLine) <= level) break
      ++end
      nextLine = nextNextLine
      nextNextLine = cm.getLine(end + 2)
    }

    return {
      from: CodeMirror.Pos(start.line, firstLine.length),
      to: CodeMirror.Pos(end, cm.getLine(end).length)
    }
  })
})
